package iq.jfreechart;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
 
import javax.swing.JFrame;
 
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTick;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.LogarithmicAxis;
import org.jfree.chart.labels.XYItemLabelGenerator;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Hour;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
 
public class LineAndShapeDemo extends JFrame {
  private static final long serialVersionUID = 8689319012171449789L;
 
  public static void main(String[] args)
  {
    final JFrame frm = new LineAndShapeDemo("Demo");
    frm.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frm.pack();
    frm.setVisible(true);
  }
  
  public LineAndShapeDemo(String title)
  {
    super(title);
    
    initComponents();
  }
 
  private void initComponents()
  {
    final XYDataset dataset = createDummyDataset();
    final JFreeChart chart = ChartFactory.createXYLineChart("BP measure", "Date/Time", "mmHg", dataset, PlotOrientation.VERTICAL, true, true, false);
    final XYLineAndShapeRenderer itemRenderer = new XYLineAndShapeRenderer(true, true) {
      public Paint getItemFillPaint(int row, int column)
      {
        final double value = dataset.getYValue(row, column);
        if (value > 180)
          return Color.BLUE;
        return super.getItemFillPaint(row, column);
      }
    };
    itemRenderer.setUseFillPaint(true);
    itemRenderer.setSeriesPaint(0, Color.GREEN);
    itemRenderer.setBaseFillPaint(Color.GREEN);
    itemRenderer.setSeriesOutlinePaint(0, Color.BLACK);
    itemRenderer.setUseOutlinePaint(true);
    chart.getXYPlot().setRenderer(itemRenderer);
    itemRenderer.setSeriesItemLabelsVisible(0, true);
    itemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() {
      private double[] max;
      {
        max = new double[dataset.getSeriesCount()];
        for (int i = 0; i < max.length; i++) {
          final int serLen = dataset.getItemCount(i);
          for (int j = 0; j < serLen; ++j) {
            final double val = dataset.getYValue(i, j);
            max[i] = Math.max(val, max[i]);
          }
        }
      }
      public String generateLabel(XYDataset dataset, int series, int item)
      {
        return (int) (dataset.getYValue(series, item) / max[series] * 100) + "%";
      }
    });
    
    final DateAxis dateAxis = new DateAxis("Date/Time") {
      private static final long serialVersionUID = -6754587411591857571L;
 
      protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea,
        RectangleEdge edge)
      {
        List ticks = super.refreshTicksHorizontal(g2, dataArea, edge);
        List newTicks = new ArrayList();
        for (Iterator it = ticks.iterator(); it.hasNext();) {
          DateTick tick = (DateTick) it.next();
          newTicks.add(new DateTick(
            tick.getDate(), tick.getText(), TextAnchor.TOP_RIGHT,
            TextAnchor.TOP_RIGHT, -Math.PI / 3));
        }
        return newTicks;
      }
    };
    dateAxis.setVerticalTickLabels(true);
    dateAxis.setTickUnit(new DateTickUnit(DateTickUnit.DAY, 1));
    chart.getXYPlot().setDomainAxis(dateAxis);
    
    LogarithmicAxis logAxis = new LogarithmicAxis("mmHg");
    logAxis.setRange(0, 1000);
    chart.getXYPlot().setRangeAxis(logAxis);
    
    getContentPane().add(new ChartPanel(chart, true));
  }
 
  protected XYDataset createDummyDataset()
  {
    final TimeSeriesCollection data = new TimeSeriesCollection();
    final TimeSeries series = new TimeSeries("Systolic", Hour.class);
    final Calendar cal = Calendar.getInstance();
    for (int i = 1; i < 32; ++ i) {
      cal.set(2005, 2, i, 0, 0);
      series.add(new Hour(cal.getTime()), 110.0 + Math.random() * 100);
    }
    data.addSeries(series);
    
    // 2005/3/17 12:00
    cal.set(2005, 2, 17, 12, 0);
    series.add(new Hour(cal.getTime()), 110.0 + Math.random() * 100);
    
//     2005/3/3 12:00
    cal.set(2005, 2, 3, 12, 0);
    series.add(new Hour(cal.getTime()), 110.0 + Math.random() * 100);
    
//     2005/3/20 12:00
    cal.set(2005, 2, 20, 12, 0);
    series.add(new Hour(cal.getTime()), 110.0 + Math.random() * 100);
    
    return data;
  }
}